/*
给你两个字符串 s 和 goal ，只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果，就返回true；否则返回 false 。

交换字母的定义是：取两个下标 i 和 j （下标从 0 开始）且满足 i != j ，接着交换 s[i] 和 s[j] 处的字符。

例如，在 "abcd" 中交换下标 0 和下标 2 的元素可以生成 "cbad" 。

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/buddy-strings
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

输入：s = "ab", goal = "ba"
输出：true
解释：你可以交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba"，此时 s 和 goal 相等。


输入：s = "ab", goal = "ab"
输出：false
解释：你只能交换 s[0] = 'a' 和 s[1] = 'b' 生成 "ba"，此时 s 和 goal 不相等。

输入：s = "aa", goal = "aa"
输出：true
解释：你可以交换 s[0] = 'a' 和 s[1] = 'a' 生成 "aa"，此时 s 和 goal 相等。

输入：s = "aaaaaaabc", goal = "aaaaaaacb"
输出：true
* */

/**
 * @param {string} s
 * @param {string} goal
 * @return {boolean}
 */
var buddyStrings = function(s, goal) {
  if(s.length !== goal.length) return false;
  if(s === goal) return s.length > new Set(s).size; //为true 就说明有重复的 有重复的 就一定能交换成功(交换任意相同的两个字符即可)

  let temp = []; // [s,g,g,s]
  for (let i = 0; i < s.length; i++) {
    if (s[i] !== goal[i]) {
      temp.push(s[i], goal[i]);
    }
    if(temp.length > 4) return false; //不相同的字符超过了2个 那一定就没法通过仅仅交换两个字符来达到效果了
  }

  return (temp.length === 4) && temp[0] === temp[3] && temp[1] === temp[2]
};



/*var buddyStrings = function(s, goal) {
  if (s.length != goal.length) {
    return false;
  }

  if (s === goal) {
    const count = new Array(26).fill(0);
    for (let i = 0; i < s.length; i++) {
      count[s[i].charCodeAt() - 'a'.charCodeAt()]++;
      if (count[s[i].charCodeAt() - 'a'.charCodeAt()] > 1) {
        return true;
      }
    }
    return false;
  } else {
    let first = -1, second = -1;
    for (let i = 0; i < s.length; i++) {
      if (s[i] !== goal[i]) {
        if (first === -1)
          first = i;
        else if (second === -1)
          second = i;
        else
          return false;
      }
    }

    return (second !== -1 && s[first] === goal[second] && s[second] === goal[first]);
  }
};*/
// 时间复杂度：O(N)，其中 N 为字符串的长度。我们至多遍历字符串两遍。
//
// 空间复杂度：O(C)。需要常数个空间保存字符串的字符统计次数，我们统计所有小写字母的个数，因此 C = 26。
